package com.bdzl.auth.util;

import net.coobird.thumbnailator.Thumbnails;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.*;
import java.util.Iterator;
import java.util.Random;

public class ImageUtil {


    public static int targetLength = 55;//小图长
    public static int targetWidth = 45;//小图宽
    static int circleR = 10;//半径
    static int r1 = 4;//距离点
    /**
     * 随机获取图片
     *
     * @return
     * @throws Exception
     */
    public static BufferedImage Image() throws Exception {
        Random random = new Random();
        Integer r = random.nextInt(Integer.valueOf("6"));
        String path =r.toString();
        String last =  ".png";
        BufferedImage bufferedImage = null;
        try{
            ClassPathResource classPathResource = new ClassPathResource("check/"+path+last);
            InputStream inputStream = classPathResource.getInputStream();
//            InputStream inputStream = new FileInputStream(path+last);
            bufferedImage = ImageIO.read(inputStream);
        }catch (Exception e){
            e.printStackTrace();
        }
        return bufferedImage;
    }

    /**
     * 剪切图片
     *
     * @param bufferedImage 剪切的图片
     * @param x             剪切区域的x轴
     * @param y             剪切区域的y轴
//     * @param length        剪切的图片长度
//     * @param width         剪切图片的宽度
     * @return
     * @throws IOException
     */
    public static BufferedImage getMarkImage(BufferedImage bufferedImage, int x, int y) throws IOException {
        InputStream is = null;
        ImageInputStream iis = null;
        try {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "png", os);
            is = new ByteArrayInputStream(os.toByteArray());
            Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName("png");
            ImageReader reader = it.next();
            //获取图片流
            iis = ImageIO.createImageInputStream(is);
            reader.setInput(iis, true);
            ImageReadParam param = reader.getDefaultReadParam();
            Rectangle rect = new Rectangle(x, y, targetLength, targetWidth);
            param.setSourceRegion(rect);
            BufferedImage bi = reader.read(0, param);
            return bi;
        } finally {
            if (is != null) {
                is.close();
            }
            if (iis != null) {
                iis.close();
            }
        }
    }



    public static int[][] getBlockData() {

        int[][] data = new int[targetLength][targetWidth];
        double x2 = targetLength - circleR;

        //随机生成圆的位置
        double h1 = circleR + Math.random() * (targetWidth - 3 * circleR - r1);
        double po = circleR * circleR;

        double xbegin = targetLength - circleR - r1;
        double ybegin = targetWidth - circleR - r1;

        for (int i = 0; i < targetLength; i++) {
            for (int j = 0; j < targetWidth; j++) {
                double d3 = Math.pow(i - x2, 2) + Math.pow(j - h1, 2);
                double d2 = Math.pow(j - 2, 2) + Math.pow(i - h1, 2);
                if ((j <= ybegin && d2 <= po) || (i >= xbegin && d3 >= po)) {
                    data[i][j] = 0;
                } else {
                    data[i][j] = 1;
                }

            }
        }
        return data;
    }

    /**
     * @param oriImage
     * @param targetImage
     * @param templateImage
     * @param x
     * @param y             void
     * @throws
     * @Createdate: 2019年1月24日上午10:51:30
     * @Title: cutByTemplate
     * @Description: 生成小图片、给大图片添加阴影
     * @author mzl
     */
    public static void cutByTemplate(BufferedImage oriImage, BufferedImage targetImage, int[][] templateImage, int x, int y) {
        for (int i = 0; i < targetLength; i++) {
            for (int j = 0; j < targetWidth; j++) {
                int rgb = templateImage[i][j];
                // 原图中对应位置变色处理
                int rgb_ori = oriImage.getRGB(x + i, y + j);

                if (rgb == 1) {
                    //抠图上复制对应颜色值
                    targetImage.setRGB(i, j, rgb_ori);
                    //原图对应位置颜色变化
                    oriImage.setRGB(x + i, y + j, rgb_ori & 0x363636 );
                }else{
                    //这里把背景设为透明
                    targetImage.setRGB(i, j, rgb_ori & 0x00ffffff);
                }
            }
        }
    }
    /**
     * 裁剪区块
     *
     * @param oriImage    原图
     * @param targetImage 裁剪图
     * @param blockImage  滑块
     * @param x           裁剪点x
     * @param y           裁剪点y
     */
    public static void cutImg(BufferedImage oriImage, BufferedImage targetImage, int[][] blockImage, int x, int y) {
        for (int i = 0; i < targetLength; i++) {
            for (int j = 0; j < targetWidth; j++) {
                int _x = x + i;
                int _y = y + j;
                int rgb = blockImage[i][j];
                // 原图中对应位置变色处理
                if (rgb == 1) {
                    int rgb_ori = oriImage.getRGB(_x, _y);
                    //抠图上复制对应颜色值
                    targetImage.setRGB(_x, _y, rgb_ori);
                    //原图对应位置颜色变化
                    oriImage.setRGB(_x, _y, Color.LIGHT_GRAY.getRGB());
                } else if (rgb == 2) {
                    targetImage.setRGB(_x, _y, Color.WHITE.getRGB());
                    oriImage.setRGB(_x, _y, Color.GRAY.getRGB());
                }
            }
        }
    }





    //高斯模糊图片
    public static ConvolveOp getGaussianBlurFiler(int radius,boolean horizontal){
        if(radius < 1){
            throw new IllegalArgumentException("Radius must be >= 1");
        }
        int size = radius *2 +1;
        float [] data = new float[size];
        float sigma = radius/ 3.0f;
        float twoSigmaSquare = 2.0f * sigma * sigma;
        float sigmaRoot = (float)Math.sqrt(twoSigmaSquare * Math.PI);
        float total = 0.0f;
        for(int i = -radius; i<=radius ; i++){
            float distance = i * i ;
            int index = i+radius;
            data[index] = (float)Math.exp(-distance / twoSigmaSquare) / sigmaRoot;
            total += data[index];
        }
        for (int i = 0 ; i < data.length ; i++){
            data[i]/=total;
        }
        Kernel kernel = null;
        if(horizontal){
            kernel = new Kernel(size , 1 , data);
        }else{
            kernel = new Kernel(1,size,data);
        }
        return new ConvolveOp(kernel,ConvolveOp.EDGE_NO_OP,null);
    }
    public static BufferedImage simpleBlur(BufferedImage src,BufferedImage dest){
        BufferedImageOp op = getGaussianBlurFiler(2,false);
        return op.filter(src,dest);
    }

    /**
     * 图片添加边框
     * @param image
     * @param x
     * @param y
     * @param width
     * @param height
     * @return
     */
    public static BufferedImage imagesFrame(BufferedImage image ,int x,int y ,int width,int height){
        Graphics g = image.getGraphics();
        g.setColor(Color.LIGHT_GRAY);
        g.drawRect(x,y,width,height);
        return image;
    }

    public static BufferedImage imagesFrameMin(BufferedImage image ){
        int height = 54;
        int width = 54;
        Graphics g = image.getGraphics();
        Color cl = new Color(173,216,230);
        g.setColor(cl);
        g.drawRect(0,0,width,height);
        return image;
    }


    /**
     * 对图片进行旋转
     *
     * @param src   被旋转图片
     * @param angel 旋转角度
     * @return 旋转后的图片
     */
    public static BufferedImage rotate(Image src, int angel) {
        int src_width = src.getWidth(null);
        int src_height = src.getHeight(null);
        // 计算旋转后图片的尺寸
        Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(
                src_width, src_height)), angel);
        BufferedImage res = null;
        res = new BufferedImage(rect_des.width, rect_des.height,
                BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = res.createGraphics();
        // 进行转换
        g2.translate((rect_des.width - src_width) / 2,
                (rect_des.height - src_height) / 2);
        g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);

        g2.drawImage(src, null, null);
        return res;
    }

    /**
     * 计算旋转后的图片
     *
     * @param src   被旋转的图片
     * @param angel 旋转角度
     * @return 旋转后的图片
     */
    public static Rectangle CalcRotatedSize(Rectangle src, int angel) {
        // 如果旋转的角度大于90度做相应的转换
        if (angel >= 90) {
            if (angel / 90 % 2 == 1) {
                int temp = src.height;
                src.height = src.width;
                src.width = temp;
            }
            angel = angel % 90;
        }

        double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
        double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
        double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
        double angel_dalta_width = Math.atan((double) src.height / src.width);
        double angel_dalta_height = Math.atan((double) src.width / src.height);

        int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha
                - angel_dalta_width));
        int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha
                - angel_dalta_height));
        int des_width = src.width + len_dalta_width * 2;
        int des_height = src.height + len_dalta_height * 2;
        return new Rectangle(new Dimension(des_width, des_height));
    }

    /**
     * MultipartFile 转 BufferedImage
     * @param file
     * @return
     */
    public static BufferedImage InputImage(MultipartFile file) {
        BufferedImage srcImage = null;
        try {
            FileInputStream in = (FileInputStream) file.getInputStream();
            srcImage = ImageIO.read(in);
        } catch (IOException e) {
            System.out.println("读取图片文件出错！" + e.getMessage());
        }
        return srcImage;
    }

    /**
     * 压缩图片
     * @param mult
     */
    public static MultipartFile compress(MultipartFile mult) throws IOException {
        int max_size=1024<<9; //500KB
        System.out.println("Init:"+mult.getSize());
        if (max_size>=mult.getSize()){
            return mult;
        }else{
            BufferedImage image=ImageIO.read(mult.getInputStream());
            File file=File.createTempFile("temp",mult.getOriginalFilename());

            if (image.getWidth()>1080){ //先调整分辨率
                Thumbnails.of(mult.getInputStream()).width(1080).toFile(file);
            }

            System.out.println("File1:"+file.length());
            if (file.length()>max_size){ //在调整图片质量
                Thumbnails.of(file).outputQuality(0.7f).toFile(file);
            }

            mult= new MockMultipartFile(mult.getName(),mult.getOriginalFilename(),mult.getContentType(),new FileInputStream(file));
            System.out.println("File2:"+file.length());
            System.out.println("Mult:"+mult.getSize());
            file.deleteOnExit();
            return mult;
        }
    }

    public static void main(String[] args) {
        int m=1024<<9;
        System.out.println(3555878>m);
    }

}
